package com.rw.coco.reply;

import com.rw.coco.api.log.CocoLogger;
import com.rw.coco.api.reply.CocoReplyApi;
import com.rw.coco.api.reply.mapper.AdvancedReply;
import com.rw.coco.api.reply.mapper.DiceReply;
import com.rw.coco.api.reply.mapper.EntertainingReply;
import com.rw.coco.api.reply.mapper.OptionReply;
import com.rw.coco.reply.impl.PropertiesAdvancedReply;
import com.rw.coco.reply.impl.PropertiesDiceReply;
import com.rw.coco.reply.impl.PropertiesEntertainingReply;
import com.rw.coco.reply.impl.PropertiesOptionReply;
import com.rw.coco.reply.reader.CocoPropertiesReader;
import com.rw.tool.util.properties.ReadPropertiesException;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 可可回复的配置文件文件实现
 */
public class PropertiesCocoReplyApi implements CocoReplyApi {
    // 读取配置文件的特化reader
    private final CocoPropertiesReader reader;

    // 默认高级设置回复的路径
    private static final String ADVANCE_REPLY = "com/rw/coco/reply/advanceReply.properties";

    // 默认骰子相关回复的路径
    private static final String DICE_REPLY = "com/rw/coco/reply/diceReply.properties";

    // 默认娱乐相关回复的路径
    private static final String ENTERTAINING_REPLY = "com/rw/coco/reply/entertainingReply.properties";

    // 默认设置类相关的路径
    private static final String OPTION_REPLY = "com/rw/coco/reply/optionReply.properties";

    // 所有设置文件的路径列表
    private static final List<String> DEFAULT_REPLY_PROP = Arrays.asList(
            ADVANCE_REPLY, DICE_REPLY, ENTERTAINING_REPLY, OPTION_REPLY
    );

    /**
     * 创建一个根据配置文件进行回复的可可回复API
     *
     * @param cocoLogger 日志输出接口
     */
    public PropertiesCocoReplyApi(CocoLogger cocoLogger) {
        this(getDefaultUrlList(), cocoLogger);
    }

    /**
     * 创建一个根据配置文件进行回复的可可回复API
     *
     * @param cocoLogger 日志输出接口
     * @param path       外置配置文件的路径
     */
    public PropertiesCocoReplyApi(String path, CocoLogger cocoLogger) {
        this(new File(path), cocoLogger);
    }


    /**
     * 创建一个根据配置文件进行回复的可可回复API
     *
     * @param cocoLogger 日志输出接口
     * @param file       外置配置文件的file类
     */
    public PropertiesCocoReplyApi(File file, CocoLogger cocoLogger) {
        this(toURL(file), cocoLogger);
    }

    /**
     * 创建一个根据配置文件进行回复的可可回复API
     *
     * @param cocoLogger 日志输出接口
     * @param url        外置配置文件的url链接
     */
    public PropertiesCocoReplyApi(URL url, CocoLogger cocoLogger) {
        this(Collections.singletonList(url), cocoLogger);
    }

    /**
     * 创建一个根据配置文件进行回复的可可回复API
     *
     * @param cocoLogger 日志输出接口
     * @param urlList    多个外置配置文件的url链接列表
     */
    public PropertiesCocoReplyApi(List<URL> urlList, CocoLogger cocoLogger) {
        // 读取配置文件
        CocoPropertiesReader temp;
        try {
            temp = new CocoPropertiesReader(urlList);
        } catch (IllegalArgumentException e) {
            cocoLogger.warn("未找到对应的配置文件！即将启用默认的配置文件!");
            temp = new CocoPropertiesReader(getDefaultUrlList());
        }

        reader = temp;
    }

    private static URL toURL(File file) {
        try {
            return file.toURI().toURL();
        } catch (MalformedURLException e) {
            throw new ReadPropertiesException(e);
        }
    }

    private static List<URL> getDefaultUrlList() {
        ClassLoader classLoader = PropertiesCocoReplyApi.class.getClassLoader();
        return PropertiesCocoReplyApi.DEFAULT_REPLY_PROP.stream()
                .map(classLoader::getResource)
                .collect(Collectors.toList());
    }

    @Override
    public AdvancedReply getAdvancedReply() {
        return new PropertiesAdvancedReply(reader);
    }

    @Override
    public DiceReply getDiceReply() {
        return new PropertiesDiceReply(reader);
    }

    @Override
    public EntertainingReply getEntertainingReply() {
        return new PropertiesEntertainingReply(reader);
    }

    @Override
    public OptionReply getOptionReply() {
        return new PropertiesOptionReply(reader);
    }
}
